package com.whut.monitor.controller;

import com.whut.monitor.netty.handler.ServerInboundHandler;
import com.whut.monitor.service.IHbaseService;
import com.whut.monitor.util.SendMessageUtil;
import com.whut.monitor.util.SystemUtil;
import com.whut.monitor.util.ThreadUtil;
import com.whut.monitor.util.ZipUtil;
import com.whut.monitor.vo.DiagnosisSensorVo;
import com.whut.monitor.vo.Grid;
import com.whut.monitor.vo.ResponseMsg;
import com.whut.monitor.websocket.PollWebSocketServlet;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import static com.whut.monitor.util.DateUtil.getNowTimeMS;
import static com.whut.monitor.util.FileUtil.saveString;
import static com.whut.monitor.util.SshUtil.cmdModelRealTimePredictionNoShell;
import static com.whut.monitor.util.WuzhongUtil.fileSavePath;
import static com.whut.monitor.util.SshUtil.cmdModelRealTimePrediction;
import static com.whut.monitor.util.SystemUtil.*;

/**
 * 数据分析接口，云计算、传感器诊断等
 *
 * @author Sandeepin
 */
@Controller
@RequestMapping("/analysis")
public class AnalysisController {
    private static final Logger logger = Logger.getLogger(AnalysisController.class);

    @Autowired
    private IHbaseService hbaseService;

    @Autowired
    private PollWebSocketServlet webSocketServlet;

    /**
     * 返回HTML页面测试
     *
     * @param date   日期
     * @param writer 输出流
     * @throws IOException IO
     */
    @RequestMapping("/html")
    public void html(String date, Writer writer) throws IOException {
        String out = "<!DOCTYPE html><html><head><title>HTML测试</title><meta charset=\"utf-8\"><meta name=\"description\"content=\"Sandeepin\"><link rel=\"shortcut\ticon\"href=\"//img.jfz.me/favicon.ico\"><script src=\"//cdn.bootcss.com/jquery/2.2.3/jquery.min.js\"></script><link href=\"//cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css\"rel=\"stylesheet\"><link href=\"//cdn.bootcss.com/bootstrap-table/1.11.1/bootstrap-table.min.css\"rel=\"stylesheet\"><script src=\"//cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js\"></script><script src=\"//cdn.bootcss.com/bootstrap-table/1.11.1/bootstrap-table.min.js\"></script><script src=\"//cdn.bootcss.com/bootstrap-table/1.11.1/locale/bootstrap-table-zh-CN.min.js\"></script><link rel=\"stylesheet\"href=\"//59.69.101.206/WhutMonitor/css/assets/css/ace.min.css\"/><link rel=\"stylesheet\"href=\"//59.69.101.206/WhutMonitor/css/assets/css/ace-rtl.min.css\"/><link rel=\"stylesheet\"href=\"//59.69.101.206/WhutMonitor/css/assets/css/ace-skins.min.css\"/></head><body style=\"background-color:white;margin-top:70px;font: 16px/1.5 'Helvetica Neue',Helvetica,Arial,'Microsoft Yahei','Hiragino Sans GB','Heiti SC','WenQuanYiMicro Hei',sans-serif;\"><div class=\"widget-box\"style=\"margin:16px 24px;padding-bottom:15px;text-align:center;\"><div class=\"widget-header header-color-blue\"style=\"border-top-left-radius:10px;border-top-right-radius:10px;\"><h4 style=\"color:white;font-family:'Microsoft Yahei';\">传感器每天监测汇报</h4></div><div class=\"widget-body\"style=\"border-bottom-right-radius:10px;border-bottom-left-radius:10px;min-height:500px;\"><div class=\"widget-main\"><div class=\"row\"><p>日期" + date + "</p></body></html>";
        writer.write(out);
    }

    /**
     * 获取MD5的前8位
     *
     * @param request HttpServletRequest
     * @return md5
     * @throws NoSuchAlgorithmException 异常
     */
    @RequestMapping("/md5")
    @ResponseBody
    public String statidata(HttpServletRequest request) throws NoSuchAlgorithmException {
        String md5str = getMd5(getNowTimeMS() + request.getSession().toString());
        return md5str.substring(0, 8);
    }

    /**
     * Spark分布式计算任务上传py文件和数据
     *
     * @param file    文件
     * @param request http
     * @return 信息
     */
    @RequestMapping("/sparkupload")
    @ResponseBody
    public ResponseMsg uploadbin(@RequestParam MultipartFile file, HttpServletRequest request) {
        ResponseMsg j = new ResponseMsg();
        if (file.isEmpty()) {
            j.setMsg("请选择要上传的spark文件！");
            return j;
        }
        // 服务器上传的spark文件所在路径
        String webSaveSparkFilePath = "/usr/local/tomcat/webapps/ROOT/file/compute/";
        if (isWindows()) {
            webSaveSparkFilePath = fileSavePath;
        }
        // 获取上传文件的原名 例464e7a80_710229096@qq.com.zip
        String saveFileName = file.getOriginalFilename();
        // 去掉后缀.zip 例464e7a80_710229096@qq.com
        String fileBaseName = FilenameUtils.getBaseName(saveFileName);
        // 获取 md5value email
        String[] tmp = fileBaseName.split("_");
        String md5value = "00000000";
        String email = "sandeepin@qq.com";
        if (tmp.length == 2) {
            md5value = tmp[0];
            email = tmp[1];
        }

        try {
            // 检测md5是否冲突
            File files = new File(webSaveSparkFilePath);
            File[] tempList = files.listFiles();
            for (int i = 0; i < tempList.length; i++) {
                if (tempList[i].isDirectory()) {
                    System.out.println("文件夹：" + tempList[i]);
                    String md5files = tempList[i].toString();
                    if (md5files.contains(md5value)) {
                        SendMessageUtil.sendMessage(md5value, "【警告】md5冲突，请刷新页面重试！", webSocketServlet);
                        j.setMsg("md5冲突！");
                        return j;
                    }
                }
            }
            // 把上传的文件放到服务器的文件夹下
            String saveFilePath = webSaveSparkFilePath + md5value + "\\";
            if (!isWindows()) {
                saveFilePath = webSaveSparkFilePath + md5value + "/";
            }
            FileUtils.copyInputStreamToFile(file.getInputStream(), new File(saveFilePath, saveFileName));


            // 检测用户的文件是否套了一层文件夹
            String firstDir = isDirZipFile(saveFilePath + saveFileName);
            if (!"run.py".equals(firstDir)) {
                // 解压文件
                ZipUtil.decompress(saveFilePath + saveFileName);
                // 强制删除zip文件
                boolean deleteZipSuccess = SystemUtil.forceDelete(new File(saveFilePath, saveFileName));
                // 创建无外层文件夹的zip文件
                System.out.println(saveFilePath + firstDir + "   del:" + deleteZipSuccess);
                if (deleteZipSuccess) {
                    ZipUtil.compress(saveFilePath + firstDir, saveFilePath + saveFileName, false);
                }
                // 删除文件夹
                File firstDirAllPath = new File(saveFilePath + firstDir);
                deleteAllFilesOfDir(firstDirAllPath);
            }
            // [异步]开始远程传输文件到spark服务器
            SendMessageUtil.sendMessage(md5value, "上传成功...", webSocketServlet);
            ThreadUtil t1 = new ThreadUtil("sparkCompute-" + md5value, saveFilePath, saveFileName,
                    md5value, email, webSocketServlet);
            t1.start();

            // 反馈用户信息
            j.setSuccess(true);
            j.setMsg("上传成功！");
        } catch (Exception e) {
            j.setMsg(e.getMessage());
            e.printStackTrace();
        }
        return j;
    }

    // 环境温度、电类传感器、FBG诊断 - 显示的HTML页面
    @RequestMapping("/diagnosissensor")
    public void diagnosissensor(String date, Writer writer) throws IOException {
        String out = "<!DOCTYPE html><html><head><title>传感器监测</title><meta charset=\"utf-8\"><meta name=\"description\"content=\"Sandeepin\"><link rel=\"shortcut\ticon\"href=\"//img.jfz.me/favicon.ico\"><script src=\"//cdn.bootcss.com/jquery/2.2.3/jquery.min.js\"></script><link href=\"//cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css\"rel=\"stylesheet\"><link href=\"//cdn.bootcss.com/bootstrap-table/1.11.1/bootstrap-table.min.css\"rel=\"stylesheet\"><script src=\"//cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js\"></script><script src=\"//cdn.bootcss.com/bootstrap-table/1.11.1/bootstrap-table.min.js\"></script><script src=\"//cdn.bootcss.com/bootstrap-table/1.11.1/locale/bootstrap-table-zh-CN.min.js\"></script><link rel=\"stylesheet\"href=\"//59.69.101.206/WhutMonitor/css/assets/css/ace.min.css\"/><link rel=\"stylesheet\"href=\"//59.69.101.206/WhutMonitor/css/assets/css/ace-rtl.min.css\"/><link rel=\"stylesheet\"href=\"//59.69.101.206/WhutMonitor/css/assets/css/ace-skins.min.css\"/></head><body style=\"background-color:white;margin-top:70px;font: 16px/1.5 'Helvetica Neue',Helvetica,Arial,'Microsoft Yahei','Hiragino Sans GB','Heiti SC','WenQuanYiMicro Hei',sans-serif;\"><div class=\"widget-box\"style=\"margin:16px 24px;padding-bottom:15px;text-align:center;\"><div class=\"widget-header header-color-blue\"style=\"border-top-left-radius:10px;border-top-right-radius:10px;\"><h4 style=\"color:white;font-family:'Microsoft Yahei';\">传感器每天监测汇报</h4></div><div class=\"widget-body\"style=\"border-bottom-right-radius:10px;border-bottom-left-radius:10px;min-height:500px;\"><div class=\"widget-main\"><div class=\"row\"><p>环境温度、电类传感器、FBG传感器" + date + "情况汇报</p><div style=\"margin-left:10px;margin-right:10px;\"><table id=\"table\"></table></div></div></div></div>受算法设计者水平所限，监测结果仅供参考。——蒋方正</div><script>$(\"#table\").bootstrapTable({url:\"http://59.69.101.206/WhutMonitor/historysearch/diagnosissensor?date=" + date + "\",cache:false,striped:true,sortName:'id',sortOrder:'asc',columns:[{field:'type',title:'传感器类别',align:'center',valign:'middle'},{field:'id',title:'传感器编号',align:'center',valign:'middle'},{field:'result',title:'监测结果',align:'center',valign:'middle',}],onLoadSuccess:function(){console.info(\"加载成功\")},onLoadError:function(){console.info(\"加载数据失败\")}})</script></body></html>";
        writer.write(out);
    }

    // 环境温度、电类传感器、FBG诊断 - 显示的HTML页面（强制显示原生数据）
    @RequestMapping("/diagnosissensorori")
    public void diagnosissensorCache(String date, Writer writer) throws IOException {
        String out = "<!DOCTYPE html><html><head><title>传感器监测</title><meta charset=\"utf-8\"><meta name=\"description\"content=\"Sandeepin\"><link rel=\"shortcut\ticon\"href=\"//img.jfz.me/favicon.ico\"><script src=\"//cdn.bootcss.com/jquery/2.2.3/jquery.min.js\"></script><link href=\"//cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css\"rel=\"stylesheet\"><link href=\"//cdn.bootcss.com/bootstrap-table/1.11.1/bootstrap-table.min.css\"rel=\"stylesheet\"><script src=\"//cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js\"></script><script src=\"//cdn.bootcss.com/bootstrap-table/1.11.1/bootstrap-table.min.js\"></script><script src=\"//cdn.bootcss.com/bootstrap-table/1.11.1/locale/bootstrap-table-zh-CN.min.js\"></script><link rel=\"stylesheet\"href=\"//59.69.101.206/WhutMonitor/css/assets/css/ace.min.css\"/><link rel=\"stylesheet\"href=\"//59.69.101.206/WhutMonitor/css/assets/css/ace-rtl.min.css\"/><link rel=\"stylesheet\"href=\"//59.69.101.206/WhutMonitor/css/assets/css/ace-skins.min.css\"/></head><body style=\"background-color:white;margin-top:70px;font: 16px/1.5 'Helvetica Neue',Helvetica,Arial,'Microsoft Yahei','Hiragino Sans GB','Heiti SC','WenQuanYiMicro Hei',sans-serif;\"><div class=\"widget-box\"style=\"margin:16px 24px;padding-bottom:15px;text-align:center;\"><div class=\"widget-header header-color-blue\"style=\"border-top-left-radius:10px;border-top-right-radius:10px;\"><h4 style=\"color:white;font-family:'Microsoft Yahei';\">传感器每天监测汇报</h4></div><div class=\"widget-body\"style=\"border-bottom-right-radius:10px;border-bottom-left-radius:10px;min-height:500px;\"><div class=\"widget-main\"><div class=\"row\"><p>环境温度、电类传感器、FBG传感器" + date + "情况汇报</p><div style=\"margin-left:10px;margin-right:10px;\"><table id=\"table\"></table></div></div></div></div>受算法设计者水平所限，监测结果仅供参考。——蒋方正</div><script>$(\"#table\").bootstrapTable({url:\"http://59.69.101.206/WhutMonitor/historysearch/diagnosissensorori?date=" + date + "\",cache:false,striped:true,sortName:'id',sortOrder:'asc',columns:[{field:'type',title:'传感器类别',align:'center',valign:'middle'},{field:'id',title:'传感器编号',align:'center',valign:'middle'},{field:'result',title:'监测结果',align:'center',valign:'middle',}],onLoadSuccess:function(){console.info(\"加载成功\")},onLoadError:function(){console.info(\"加载数据失败\")}})</script></body></html>";
        writer.write(out);
    }

    // 模型实时预测 10s一次送值
    @Scheduled(cron = "0/10 * * * * ? ")
    public void taskCycleModelRealTimePrediction10s() throws ParseException {
        System.out.println("taskCycle:ModelRealTimePrediction 10s:");
        System.out.println("SDTMap.size(): " + ServerInboundHandler.SDTMap.size());
        System.out.println("SETMap.size(): " + ServerInboundHandler.SETMap.size());
        if (ServerInboundHandler.SDTMap.size() >= 52 && ServerInboundHandler.SETMap.size() >= 4) {
            // 大哥56个输入数据源
            String[] inputSensor = new String[56];
            for (int i = 0; i < inputSensor.length; i++) {
                inputSensor[i] = "0";
            }
            // 按大哥要求赋值 TODO 这种搞法不好
            Map<String, String> ds18b20Map = new TreeMap<>(ServerInboundHandler.SDTMap);
            Map<String, String> envMap = new TreeMap<>(ServerInboundHandler.SETMap);
            int cnt = 0;
            for (String akey : ds18b20Map.keySet()) {
                String value = ds18b20Map.get(akey);
                if (value != null) {
                    inputSensor[cnt++] = value;
                }
                if (cnt == 52) {
                    break;
                }
            }
            for (String akey : envMap.keySet()) {
                String value = envMap.get(akey);
                if (value != null) {
                    inputSensor[cnt++] = value;
                }
                if (cnt == 55) {
                    break;
                }
            }

            String preLine = "please";
            String resultLine = "CFlower";
            String inputMsg = StringUtils.join(inputSensor, ",") + "\r\n";
            // 调用控制台模型预测py程序
//        String result = cmdModelRealTimePrediction(preLine, resultLine, inputMsg);
            String result = cmdModelRealTimePredictionNoShell(inputMsg, resultLine);
            System.out.println("预测结果：" + result);
            try {
                saveString("cmdModelRealTimePredictionNoShell.log", result, "");
            } catch (IOException e) {
                e.printStackTrace();
            }
            // websocket发送
            SendMessageUtil.sendMessage("modelrealtimeprediction", result, webSocketServlet);
        }
    }

    @RequestMapping("/statidata")
    @ResponseBody
    public Grid statidata(String date, String sensorID) {
        //获取开始时间
        long startTime = System.currentTimeMillis();

//		HbaseVo hbaseVo = new HbaseVo();
//		Map<String,String> map = new TreeMap<>();
//		String[][] valuesArray = hbaseService.finds(date,idArray, map);
//		String[] dateArray  = new String[map.size()];
//		int i =0;
//		// map中的key存了时间
//		for (String key : map.keySet())
//		{
//			dateArray[i] = key;
//			i++;
//		}
//		hbaseVo.setDateArray(dateArray);
//		hbaseVo.setValuesArray(valuesArray);

        // 构造返回的json数据
        Grid grid = new Grid();
        List<DiagnosisSensorVo> ul = hbaseService.findStatiData(date, sensorID);
        Long total = (long) ul.size();
        ;
        grid.setRows(ul);
        grid.setTotal(total);

        //获取结束时间
        long endTime = System.currentTimeMillis();
        logger.info("运行时间(取统计学数据整个后台):" + (endTime - startTime) + "ms 约" + (endTime - startTime) / 1000 + "s");
        return grid;
    }
}
